#ifndef MESH_HPP
#define MESH_HPP

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <string>
#include <map>
#include <Tools/SmartPointer.hpp>
#include <Rendering/Enumeration.hpp>

namespace Geometry {

//-----------------------------------------------------------------------------
class IBuffer;
class Mesh;
typedef Tools::SmartPointer<IBuffer> TIBufferPointer;
typedef Tools::SmartPointer<Mesh> TMeshPointer;
//-----------------------------------------------------------------------------
class IBuffer {
public:	
	virtual ~IBuffer();
	// Load data
	void Load(void* data);
	// Active buffer
	void Enable(int location) const;
	// Desactive buffer
	void Disable(int location) const;
	// Return buffer data type
	Rendering::VertexBufferType GetType() const;	
	// Return number of elements
	int GetNumberOfElements() const;
	// Create a buffer
	static TIBufferPointer CreateBuffer(Rendering::VertexBufferType type, int nElt);
protected:
	// Constructor
	IBuffer(Rendering::VertexBufferType type, int nElt);
	IBuffer(const IBuffer& copy);
	IBuffer& operator=(const IBuffer& copy);
	// Attributs	
	Rendering::TRenderingID bufferID; // Buffer ID
	Rendering::VertexBufferType type; // Buffer type	
	int nElements;					  // Number of elements
};
//-----------------------------------------------------------------------------
class Mesh {
public:		
	// Destructor	
	~Mesh();
	// Add a buffer
	void AddBuffer(const TIBufferPointer& buffer);
	//	Return type of primitive manage by mesh
	Rendering::MeshType GetMeshType() const;
	// Return number of vertex or index
	int GetNumberOfElements() const;
	// Load buffer
	void Enable(Rendering::VertexBufferType type, int location) const;
	// Unload buffer
	void Disable(Rendering::VertexBufferType type, int location) const;
	// Render mesh
	void Render();
	// Return true if mesh use indexed vertex
	bool IsIndexed() const;
	// Create a buffer
	static TMeshPointer CreateMesh(Rendering::MeshType type, bool indexed);
private:
	//
	typedef std::map<Rendering::VertexBufferType,TIBufferPointer> TIBufferMap;
	// Constructor
	Mesh(Rendering::MeshType type, bool indexed);
	Mesh(const Mesh& copy);	
	Mesh& operator=(const Mesh& copy);
	// Attributs
	Rendering::MeshType meshType;	// Type of mesh
	TIBufferMap buffers;			// Buffers of mesh
	bool indexed;					// Indicates if mesh is indexed or not
	int nElements;					// Store number of (drawn) elements
};
}

#endif //MESH_HPP
